var App = Object.extend({
	init: function() {
		this.currentPage = 1;
		this.blinkInterval = null;
		this.previousState = null;
		this.isParchmentReady = true;
		this.ready = false;

		this.watchNameInputInterval = setInterval(this.toggleButton.bind(this), 100);
		this.$playButton = $('.play');
		this.$playDiv = $('.play div');
        
        evtps.sub(topic.player_lvl_change,this.playerLvlChange);
        evtps.sub(topic.player_hp_change,this.playerHpChange);
        evtps.sub(topic.player_armor_change,this.playerArmorChange);
        evtps.sub(topic.player_notice_change,this.showMessage);
        evtps.sub(topic.player_death,this.playerDeath);
	},
	
	setGame: function(game) {
		this.game = game;
		this.isMobile = false;//this.game.renderer.mobile;
		this.isTablet = false;//this.game.renderer.tablet;
		this.isDesktop = !(this.isMobile || this.isTablet);
		this.supportsWorkers = !!window.Worker;
		this.ready = true;
	},

	center: function() {
		window.scrollTo(0, 1);
	},
	
	canStartGame: function() {
		if(this.isDesktop) {
			return (this.game.ready);
		} else {
			return this.game;
		}
	},
	
	tryStartingGame: function(username, starting_callback) {
		var self = this,
			$play = this.$playButton;
		
		if(username !== '') {
			if(!this.ready || !this.canStartGame()) {
				if(!this.isMobile) {
					// on desktop and tablets, add a spinner to the play button
					$play.addClass('loading');
				}
				this.$playDiv.unbind('click');
				var watchCanStart = setInterval(function() {
					log.debug("waiting game...");
					if(self.canStartGame()) {
						setTimeout(function() {
							if(!self.isMobile) {
								$play.removeClass('loading');
							}
						}, 1500);
						clearInterval(watchCanStart);
						self.startGame(username, starting_callback);
					}
				}, 100);
			} else {
				this.$playDiv.unbind('click');
				this.startGame(username, starting_callback);
			}      
		}
	},
	
	startGame: function(username, starting_callback) {
		var self = this;
		
		if(starting_callback) {
			starting_callback();
		}
		this.hideIntro(function() {
			if(!self.isDesktop) {
				// On mobile and tablet we load the map after the player has clicked
				// on the PLAY button instead of loading it in a web worker.
				self.game.loadMap();
			}
			self.start(username);
		});
	},

	start: function(username) {
		var self = this;
		var	firstTimePlaying = !storage.hasAlreadyPlayed();
		
		if(username && !this.game.started) {
/*			var optionsSet = false,
				config = this.config;

			//>>includeStart("devHost", pragmas.devHost);
			if(config.local) {
				log.debug("Starting game with local dev config.");
				this.game.setServerOptions(config.local.host, config.local.port, username);
			} else {
				log.debug("Starting game with default dev config.");
				this.game.setServerOptions(config.dev.host, config.dev.port, username);
			}
			optionsSet = true;
			//>>includeEnd("devHost");
			
			//>>includeStart("prodHost", pragmas.prodHost);
			if(!optionsSet) {
				log.debug("Starting game with build config.");
				this.game.setServerOptions(config.build.host, config.build.port, username);
			}*/
			//>>includeEnd("prodHost");

			this.center();
            storage.data.player.name = username;
			this.game.run(function() {
				$('body').addClass('started');
				if(firstTimePlaying) {
					self.toggleInstructions();
				};
			});
		}
	},

    playerHpChange: function(hp, maxHp) {
        var $hitpoints = $('#hitpoints');
        $hitpoints.addClass('white');
        setTimeout(function() {
            $hitpoints.removeClass('white');
        }, 500);

        var barWidth = Math.round((Detect.healthMaxWidth / maxHp) * (hp > 0 ? hp : 0));
        $("#hitpoints").css('width', barWidth + "px");
	},
    playerLvlChange: function(lvl) {
        $('#lvl').text(lvl);
    },
    playerArmorChange: function(armor) {
        if(armor>0){
            $('#weapon').html('<img src="data/img/gui/'+Detect.scale+'/weapon'+armor+'.png">');
        }
        armor = armor>1?armor-1:1;
        $('#armor').html('<img src="data/img/gui/'+Detect.scale+'/armor'+armor+'.png">');
    },
    playerGoldChange: function(gold) {
    },
    playerExpChange: function(exp) {
    },

	toggleButton: function() {
		var name = $('#parchment input').val(),
			$play = $('#createcharacter .play');

		if(name && name.length > 0) {
			$play.removeClass('disabled');
			$('#character').removeClass('disabled');
		} else {
			$play.addClass('disabled');
			$('#character').addClass('disabled');
		}
	},

	hideIntro: function(hidden_callback) {
		clearInterval(this.watchNameInputInterval);
		$('body').removeClass('intro');
		setTimeout(function() {
			$('body').addClass('game');
			hidden_callback();
		}, 1000);
	},

	showChat: function() {
		if(this.game.started) {
			$('#chatbox').addClass('active');
			$('#chatinput').focus();
			$('#chatbutton').addClass('active');
		}
	},

	hideChat: function() {
		if(this.game.started) {
			$('#chatbox').removeClass('active');
			$('#chatinput').blur();
			$('#chatbutton').removeClass('active');
		}
	},

	toggleInstructions: function() {
		if($('#achievements').hasClass('active')) {
			this.toggleAchievements();
			$('#achievementsbutton').removeClass('active');
		}
		$('#instructions').toggleClass('active');
	},

	toggleAchievements: function() {
		if($('#instructions').hasClass('active')) {
			this.toggleInstructions();
			$('#helpbutton').removeClass('active');
		}
		this.resetPage();
		$('#achievements').toggleClass('active');
	},

	resetPage: function() {
		var self = this,
			$achievements = $('#achievements');

		if($achievements.hasClass('active')) {
			$achievements.bind('transitionend webkitTransitionEnd oTransitionEnd', function() {
				$achievements.removeClass('page' + self.currentPage).addClass('page1');
				self.currentPage = 1;
				$achievements.unbind('transitionend webkitTransitionEnd oTransitionEnd');
			});
		}
	},
	hideWindows: function() {
		if($('#achievements').hasClass('active')) {
			this.toggleAchievements();
			$('#achievementsbutton').removeClass('active');
		}
		if($('#instructions').hasClass('active')) {
			this.toggleInstructions();
			$('#helpbutton').removeClass('active');
		}
		if($('body').hasClass('credits')) {
			this.closeInGameCredits();
		}
		if($('body').hasClass('about')) {
			this.closeInGameAbout();
		}
	},

	showAchievementNotification: function(id, name) {
		var $notif = $('#achievement-notification'),
			$name = $notif.find('.name'),
			$button = $('#achievementsbutton');

		$notif.removeClass().addClass('active achievement' + id);
		$name.text(name);
		if(this.game.storage.getAchievementCount() === 1) {
			this.blinkInterval = setInterval(function() {
				$button.toggleClass('blink');
			}, 500);
		}
		setTimeout(function() {
			$notif.removeClass('active');
			$button.removeClass('blink');
		}, 5000);
	},

	displayUnlockedAchievement: function(id) {
		var $achievement = $('#achievements li.achievement' + id);

		var achievement = this.game.getAchievementById(id);
		if(achievement && achievement.hidden) {
			this.setAchievementData($achievement, achievement.name, achievement.desc);
		}
		$achievement.addClass('unlocked');
	},

	unlockAchievement: function(id, name) {
		this.showAchievementNotification(id, name);
		this.displayUnlockedAchievement(id);

		var nb = parseInt($('#unlocked-achievements').text());
		$('#unlocked-achievements').text(nb + 1);
	},

	initAchievementList: function(achievements) {
		var self = this,
			$lists = $('#lists'),
			$page = $('#page-tmpl'),
			$achievement = $('#achievement-tmpl'),
			page = 0,
			count = 0,
			$p = null;

		_.each(achievements, function(achievement) {
			count++;

			var $a = $achievement.clone();
			$a.removeAttr('id');
			$a.addClass('achievement'+count);
			if(!achievement.hidden) {
				self.setAchievementData($a, achievement.name, achievement.desc);
			}
			$a.find('.twitter').attr('href', 'http://twitter.com/share?url=http%3A%2F%2Fbrowserquest.mozilla.org&text=I%20unlocked%20the%20%27'+ achievement.name +'%27%20achievement%20on%20Mozilla%27s%20%23BrowserQuest%21&related=glecollinet:Creators%20of%20BrowserQuest%2Cwhatthefranck');
			$a.show();
			$a.find('a').click(function() {
				 var url = $(this).attr('href');

				self.openPopup('twitter', url);
				return false;
			});

			if((count - 1) % 4 === 0) {
				page++;
				$p = $page.clone();
				$p.attr('id', 'page'+page);
				$p.show();
				$lists.append($p);
			}
			$p.append($a);
		});

		$('#total-achievements').text($('#achievements').find('li').length);
	},

	initUnlockedAchievements: function(ids) {
		var self = this;
		
		_.each(ids, function(id) {
			self.displayUnlockedAchievement(id);
		});
		$('#unlocked-achievements').text(ids.length);
	},

	setAchievementData: function($el, name, desc) {
		$el.find('.achievement-name').html(name);
		$el.find('.achievement-description').html(desc);
	},

	toggleCredits: function() {
		var currentState = $('#parchment').attr('class');

		if(this.game.started) {
			$('#parchment').removeClass().addClass('credits');
			
			$('body').toggleClass('credits');
				
			if(!this.game.player) {
				$('body').toggleClass('death');
			}
			if($('body').hasClass('about')) {
				this.closeInGameAbout();
				$('#helpbutton').removeClass('active');
			}
		} else {
			if(currentState !== 'animate') {
				if(currentState === 'credits') {
					this.animateParchment(currentState, this.previousState);
				} else {
					this.animateParchment(currentState, 'credits');
					this.previousState = currentState;
				}
			}
		}
	},
	
	toggleAbout: function() {
		var currentState = $('#parchment').attr('class');

		if(this.game.started) {
			$('#parchment').removeClass().addClass('about');
			$('body').toggleClass('about');
			if(!this.game.player) {
				$('body').toggleClass('death');
			}
			if($('body').hasClass('credits')) {
				this.closeInGameCredits();
			}
		} else {
			if(currentState !== 'animate') {
				if(currentState === 'about') {
					if(localStorage && localStorage.data) {
						this.animateParchment(currentState, 'loadcharacter');
					} else {
						this.animateParchment(currentState, 'createcharacter');
					}
				} else {
					this.animateParchment(currentState, 'about');
					this.previousState = currentState;
				}
			}
		}
	},

	closeInGameCredits: function() {
		$('body').removeClass('credits');
		$('#parchment').removeClass('credits');
		if(!this.game.player) {
			$('body').addClass('death');
		}
	},
	
	closeInGameAbout: function() {
		$('body').removeClass('about');
		$('#parchment').removeClass('about');
		if(!this.game.player) {
			$('body').addClass('death');
		}
		$('#helpbutton').removeClass('active');
	},
	
	togglePopulationInfo: function() {
		$('#population').toggleClass('visible');
	},

	openPopup: function(type, url) {
		var h = $(window).height(),
			w = $(window).width(),
			popupHeight,
			popupWidth,
			top,
			left;

		switch(type) {
			case 'twitter':
				popupHeight = 450;
				popupWidth = 550;
				break;
			case 'facebook':
				popupHeight = 400;
				popupWidth = 580;
				break;
		}

		top = (h / 2) - (popupHeight / 2);
		left = (w / 2) - (popupWidth / 2);

		newwindow = window.open(url,'name','height=' + popupHeight + ',width=' + popupWidth + ',top=' + top + ',left=' + left);
		if (window.focus) {newwindow.focus()}
	},

	animateParchment: function(origin, destination) {
		var self = this,
			$parchment = $('#parchment'),
			duration = 1;

		if(this.isMobile) {
			$parchment.removeClass(origin).addClass(destination);
		} else {
			if(this.isParchmentReady) {
				if(this.isTablet) {
					duration = 0;
				}
				this.isParchmentReady = !this.isParchmentReady;
	
				$parchment.toggleClass('animate');
				$parchment.removeClass(origin);

				setTimeout(function() {
					$('#parchment').toggleClass('animate');
					$parchment.addClass(destination);
				}, duration * 1000);
	
				setTimeout(function() {
					self.isParchmentReady = !self.isParchmentReady;
				}, duration * 1000);
			}
		}
	},

	animateMessages: function() {

	},

	resetMessagesPosition: function() {
		var message = $('#message2').text();

		$('#notifications div').removeClass('top');
		$('#message2').text('');
		$('#message1').text(message);
	},

	showMessage: function(message) {
		var $wrapper = $('#notifications div'),
			$message = $('#notifications #message2');
        $wrapper.addClass('top');
		$message.text(message);
	},
	
	resizeUi: function() {
		if(this.game) {
			if(this.game.started) {
				this.game.resize();
				this.initHealthBar();
				this.game.updateBars();
			} else {
				var newScale = this.getScaleFactor();
				this.game.renderer.rescale(newScale);
			}
		} 
	},

	//==========player===========
	playerDeath:function() {
		if($('body').hasClass('credits')) {
			$('body').removeClass('credits');
		}
		$('body').addClass('death');
	}
	//==========player===========
});